﻿/// <reference path = "Base.ts" />
namespace VantCellTypes {
    interface IDateTimePickerCellTypeParam extends IInputBaseParam {
        type: string;
        minDate: string;
        maxDate: string;
        minHour: number;
        maxHour: number;
        minMinute: number;
        maxMinute: number;
        DateTimePickerConfig: IDateTimePickerConfig;
    }
    interface IDateTimePickerConfig {
        title: string;
        confirmButtonText: string;
        cancelButtonText: string;
        itemHeight: number;
        visibleItemCount: number;
        showToolbar: boolean;
    }

    export class DateTimePickerCellType extends InputBase<IDateTimePickerCellTypeParam> {
        public setDataSource(dataSource) {
            return this.vue.setOptions(dataSource);
        }

        public onPageLoaded(info: Forguncy.Plugin.CellTypeInfo) {
            const self = this;
            const cellType = this.cellType;

            const config = cellType.DateTimePickerConfig;
            const input = this.getInputTemplate(`@click="onClick" clear-trigger="always" @change="onChange" @clear="onClear"`);

            const optionStr = this.getCustomSlotByPath(SlotPath.datetimePickerOption);

            const option = {
                template: `
<div class="fgc-vant-inputContainer">
    ${input}
    <van-popup v-model:show="show" position="bottom" teleport="body">
      <van-datetime-picker
        v-model="DateTimePickerValue"
        :type="type"
        :min-date="minDate"
        :max-date="maxDate"
        :min-hour="minHour"
        :max-hour="maxHour"
        :min-minute="minMinute"
        :max-minute="maxMinute"
        :title="title"
        :confirm-button-text="confirmButtonText"
        :cancel-button-text="cancelButtonText"
        :item-height="itemHeight"
        :visible-item-count="visibleItemCount"
        :swipe-duration="swipeDuration"
        :show-toolbar="showToolbar"
        :formatter="onFormatter"
        :filter="onFilter"
        @cancel="show = false"
        @confirm="onFinish"
      >
        ${ optionStr ? "<template #option='data'>" + optionStr + "</template>" : "" }
      </van-datetime-picker>
    </van-popup>
</div>`,
                data() {
                    const baseData = self.getData(cellType);
                    const data = {
                        value: "",
                        show: false,
                        cellValue: undefined,
                        ...getPickerValidToolbarOption(config),
                        DateTimePickerValue: cellType.type === "time" ? `${cellType.minHour}:${cellType.minMinute}` : new Date(),
                        ...this.getValidMinDateAndMaxDate(cellType.minDate, cellType.maxDate),
                        type: cellType.type,
                        minDate: this.convertToDate(cellType.minDate),
                        maxDate: this.convertToDate(cellType.maxDate),
                        minHour: cellType.minHour,
                        maxHour: cellType.maxHour,
                        minMinute: cellType.minMinute,
                        maxMinute: cellType.maxMinute,
                    };
                    config.showToolbar = !!config.showToolbar;

                    return { ...baseData, ...config, ...data, };
                },
                methods: this.getDefaultMethods({
                    onFinish() {
                        this.show = false;
                        if (typeof this.DateTimePickerValue === "string" &&
                            (<string>this.DateTimePickerValue).indexOf(":") > 0 &&
                            this.type === "time") {
                            const start = Forguncy.ConvertDateToOADate(new Date("2001/1/1 " + this.DateTimePickerValue));
                            const end = Forguncy.ConvertDateToOADate(new Date("2001/1/1"));
                            this.cellValue = start - end;
                        }
                        else {
                            this.cellValue = Forguncy.ConvertDateToOADate(this.DateTimePickerValue);
                        }
                        this.updateValue();
                        self.commitValue();
                        self.validate();
                    },
                    onClear() {
                        this.cellValue = null;
                        self.commitValue();
                        self.validate();
                    },
                    getValidMinDateAndMaxDate(minDateValue, maxDateValue, autoFill = true) {
                        let minDate = this.convertToDate(minDateValue) || this.minDate;
                        let maxDate = this.convertToDate(maxDateValue) || this.maxDate;

                        const returnResult = () => ({ minDate, maxDate, });

                        if (!autoFill) {
                            return returnResult();
                        }

                        if (!minDate && maxDate) {
                            minDate = new Date(maxDate.valueOf());
                            minDate.setFullYear(minDate.getFullYear() - 20);
                            return returnResult();
                        }

                        if (!maxDate && minDate) {
                            maxDate = new Date(minDate.valueOf());
                            maxDate.setFullYear(maxDate.getFullYear() + 20);
                            return returnResult();
                        }

                        return returnResult();
                    },
                    onFormatter(type, value) {
                        return self.formatter(type, value);
                    },
                    onFilter(type, options) {
                        return self.filter(type, options);
                    },
                    onClick() {
                        if (!self.isReadOnly() && !self.isDisabled()) {
                            this.show = true;
                        }
                    },
                    onChange(value) {
                        this.value = value ?? "";
                        this.onFinish();
                    },
                    getValue() {
                        return this.cellValue;
                    },
                    setValue(value) {
                        if (this.cellValue !== value) {
                            this.cellValue = value;
                            this.updateValue();
                        }
                    },
                    updateValue() {
                        const result = Forguncy.FormatHelper.format(this.getFormatStr(), this.cellValue);
                        this.value = result?.text;

                        let dateTime = new Date();
                        if (this.cellValue) {
                            dateTime = Forguncy.ConvertOADateToDate(this.cellValue);
                        }
                        if (this.type === "time") {
                            this.DateTimePickerValue = `${dateTime.getHours()}:${dateTime.getMinutes()}`;
                        }
                        else {
                            this.DateTimePickerValue = dateTime;
                        }
                    },
                    getFormatStr() {
                        switch (this.type) {
                            case "date":
                                return "yyyy-MM-dd";
                            case "time":
                                return "HH:mm";
                            case "year-month":
                                return "yyyy-MM";
                            case "month-day":
                                return "MM-dd";
                            case "datehour":
                                return "yyyy-MM-dd HH:mm";
                            case "datetime":
                                return "yyyy-MM-dd HH:mm";
                            default:
                                return "yyyy-MM-dd";
                        }
                    },
                    convertToDate(value: string) {
                        return DateUtil.ConvertToDate(self.evaluateFormula(value), null) ?? undefined;
                    },
                }),
                mounted() {
                    self.setFontToInputDom(this);

                    $(".van-field__control", self.container).attr("readonly", "readonly");
                },
                watch: {
                    show(value) {
                        if (!value && !this.showToolbar) {
                            this.onFinish();
                        }
                    }
                }

            };

            this.onDependenceCellValueChanged(() => {
                const { minDate, maxDate } = this.vue.getValidMinDateAndMaxDate(cellType.minDate, cellType.maxDate, false);

                if (this.isFormula(cellType.minDate)) {
                    this.vue.minDate = minDate;
                }
                if (this.isFormula(cellType.maxDate)) {
                    this.vue.maxDate = maxDate;
                }
            });

            this.createVueApp(option);
            super.onPageLoaded(info);
        }
        // 留给用户重写
        public formatter(type, value) {
            return value;
        }
        // 留给用户重写
        public filter(type, options) {
            return options;
        }
        public ShowPopup() {
            this.vue.onClick();
        }
    }
}

Forguncy.Plugin.CellTypeHelper.registerCellType("Vant.CellTypes.DateTimePicker, Vant", VantCellTypes.DateTimePickerCellType);